package com.example.blog.controller;

import com.example.blog.common.ResultAjax;
import com.example.blog.common.SessionUtil;
import com.example.blog.model.ArticleInfo;
import com.example.blog.model.UserInfo;
import com.example.blog.model.vo.UserInfoVO;
import com.example.blog.service.IArticleService;
import com.example.blog.service.IUserService;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * @Author YJ
 * @Date 2023/9/5 15:32
 * Description:
 */
@RestController
@RequestMapping("/article")
public class ArticleController {
    @Resource
    private IArticleService articleService;
    @Resource
    private IUserService userService;

    @Resource
    private ThreadPoolTaskExecutor taskExecutor;

    private static final int _DESC_LENGTH = 120;

    @GetMapping("/mylist")
    public ResultAjax myList(HttpServletRequest request) {
        //1.得到当前用户
        UserInfo user = SessionUtil.getUser(request);
        if (user == null) {
            return ResultAjax.fail(-1, "请先登录！");
        }
        //2.根据用户id查询此用户发表的所有文章
        List<ArticleInfo> listById = articleService.getListById(user.getUserId());
        if (listById != null && listById.size() > 0) {
            //并行处理  listById集合
            listById.stream().parallel().forEach((articleInfo -> {
                if (articleInfo.getContent().length() > _DESC_LENGTH) {
                    articleInfo.setContent(articleInfo.getContent().substring(0, _DESC_LENGTH));
                }
            }));
        }
        //查询用户发表文章数
        int readCount = articleService.getReadCountByUserId(user.getUserId());
        UserInfoVO userInfoVO = new UserInfoVO();
        userInfoVO.setUsername(user.getUsername());
        userInfoVO.setArtCount(readCount);
        HashMap<String,Object> result = new HashMap<>();
        result.put("user",userInfoVO);
        result.put("art",listById);
        //3.返回结果
        return ResultAjax.success(result);
    }

    @PostMapping("/del")
    public ResultAjax del(HttpServletRequest request, Integer blogId) {
        //1.参数校验
        if (blogId == null || blogId <= 0) {
            return ResultAjax.fail(-1, "参数错误！");
        }
        //2.得到当前用户
        UserInfo user = SessionUtil.getUser(request);
        if (user == null) {
            return ResultAjax.fail(-2, "请先登录！");
        }
        //3.判断文章的归属人
        //删除操作
        int result = articleService.del(blogId, user.getUserId());
        //4.返回结果
        return ResultAjax.success(result);
    }


    @PostMapping("/add")
    public ResultAjax add(HttpServletRequest request, ArticleInfo articleInfo) {
        //1.参数校验
        if (articleInfo == null
                || !StringUtils.hasLength(articleInfo.getTitle())
                || !StringUtils.hasLength(articleInfo.getContent())) {
            return ResultAjax.fail(-1, "参数错误！");
        }
        //2.组装数据
        UserInfo user = SessionUtil.getUser(request);
        if (user == null) {
            return ResultAjax.fail(-2, "请先登录！");
        }
        articleInfo.setUserId(user.getUserId());
        //3.添加操作
        int result = articleService.add(articleInfo);
        //4.返回结果
        return ResultAjax.success(result);
    }

    @GetMapping("update_init")
    public ResultAjax updateInit(HttpServletRequest request, Integer blogId) {
        //1.参数校验
        if (blogId == null || blogId <= 0) {
            return ResultAjax.fail(-1, "参数错误！");
        }
        //2.得到当前用户的id
        UserInfo user = SessionUtil.getUser(request);
        if (user == null) {
            return ResultAjax.fail(-2, "请先登录！");
        }
        //3.查询文章/校验权限
        ArticleInfo articleByIdAndBlogId = articleService.getArticleByIdAndBlogId(blogId, user.getUserId());
        //4.返回结果
        return ResultAjax.success(articleByIdAndBlogId);
    }

    @PostMapping("/update")
    public ResultAjax update(HttpServletRequest request, ArticleInfo articleInfo) {
        //1.参数校验
        if (articleInfo == null
                || !StringUtils.hasLength(articleInfo.getTitle())
                || !StringUtils.hasLength(articleInfo.getContent())
                || articleInfo.getBlogId() == 0) {
            return ResultAjax.fail(-1, "参数错误！");
        }
        //2.组装数据
        UserInfo user = SessionUtil.getUser(request);
        if (user == null) {
            return ResultAjax.fail(-2, "请先登录！");
        }
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        articleInfo.setUpdateTime(timestamp);
        //3.修改数据
        int result = articleService.updateByUserId(articleInfo.getBlogId(),
                articleInfo.getTitle(), articleInfo.getContent(),
                user.getUserId(), articleInfo.getUpdateTime());
        //4.返回结果
        return ResultAjax.success(result);
    }
    @GetMapping("detail")
    public ResultAjax detail(Integer blogId) throws ExecutionException, InterruptedException {
        //1.参数校验
        if (blogId == null || blogId <= 0) {
            return ResultAjax.fail(-1, "参数错误！");
        }
        //2.查询文章详情信息
        ArticleInfo detailByBlogId = articleService.getDetailByBlogId(blogId);
        if(detailByBlogId == null || detailByBlogId.getBlogId() <= 0) {
            return ResultAjax.fail(-1,"非法参数！");
        }
        //3.根据blogId查询用户信息
        //todo:调用service
        FutureTask<UserInfoVO> userInfoFutureTask = new FutureTask<>(() -> {
            return userService.selectByUserId(detailByBlogId.getUserId());
        });
        taskExecutor.submit(userInfoFutureTask);
        //4.根据userId查询用户发表总文章数
        //todo:调用service
        FutureTask<Integer> articleCountFutureTask = new FutureTask<>(() -> {
            return articleService.getReadCountByUserId(detailByBlogId.getUserId());
        });
        taskExecutor.submit(articleCountFutureTask);
        //5.组装数据
        //等待线程池执行完成
        UserInfoVO userInfoVO = userInfoFutureTask.get();
        int articleCount = articleCountFutureTask.get();
        userInfoVO.setArtCount(articleCount);
        HashMap<String,Object> result = new HashMap<>();
        result.put("user",userInfoVO);
        result.put("art",detailByBlogId);
        //6.返回结果
        return ResultAjax.success(result);
    }

    @PostMapping("/increment_rcount")
    public ResultAjax incrementReadCount(Integer blogId) {
        //1.校验参数
        if (blogId == null || blogId <= 0) {
            return ResultAjax.fail(-1, "参数错误！");
        }
        //2.更改数据库
        int result = articleService.incrementReadCount(blogId);
        //3.返回结果
        return ResultAjax.success(result);
    }

    @GetMapping("/getlistbypage")
    public ResultAjax getListByPage(Integer pIndex,Integer pSize) throws ExecutionException, InterruptedException {
        //1.加工参数
        if(pIndex == null || pIndex < 1) {
            //参数矫正
            pIndex = 1;
        }
        if(pSize == null || pSize < 1) {
            //参数矫正
            pSize = 2;
        }
        //2.并发进行文章列表和总页数的查询
        Integer finalPSize = pSize;
        Integer finalPIndex = pIndex;
        FutureTask<List<ArticleInfo>> listTask = new FutureTask<>(() -> {
            //分页公式
            int offSet = finalPSize *(finalPIndex - 1);
            return articleService.getListByPage(finalPSize,offSet);
        });
        FutureTask<Integer> sizeTask = new FutureTask<>(() -> {
            int countTemp = articleService.getCount();
            double sizeTemp = (countTemp*1.0)/(finalPSize * 1.0);
            return (int)Math.ceil(sizeTemp);
        });
        taskExecutor.submit(listTask);
        taskExecutor.submit(sizeTask);
        List<ArticleInfo> list = listTask.get();
        int size = sizeTask.get();
        //3.组装数据
        HashMap<String,Object> result = new HashMap<>();
        result.put("list",list);
        result.put("size",size);
        //4.返回结果给前端
        return ResultAjax.success(result);
    }
}
